package com.lvan.util;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;

import com.lvan.constant.Email;
import com.lvan.constant.NotNull;
import com.lvan.constant.Size;
import com.lvan.constant.TelPhone;
import com.lvan.constant.ValidateRecord;

public class InputValidate<T> {
	public Set<ValidateRecord> validate(T t,boolean newRecord) {
		Field[] fs = t.getClass().getDeclaredFields();
		Set<ValidateRecord> s = new HashSet<ValidateRecord>();
		try {
			for (Field f : fs) {
				if (f.isAnnotationPresent(NotNull.class)) {
					Object o = getValueFromMethodName(f.getName(), t);
					if(o==null && !newRecord) {
						continue;
					}
					if (o == null
							|| (f.getType().getName()
									.equals(java.lang.String.class.getName()) && (o
									.toString().trim().length() == 0))) {
						ValidateRecord m = new ValidateRecord();
						m.setAnnotationClass(NotNull.class);
						m.setMessage(f.getAnnotation(NotNull.class).message());
						m.setField(f.getName());
						s.add(m);
					}
				}
				if (f.isAnnotationPresent(Email.class)) {
					Object o = getValueFromMethodName(f.getName(), t);
					if(o==null) {
						continue;
					}
					String email = o.toString();
					if(!email.matches(f.getAnnotation(Email.class).reg())) {
						ValidateRecord m = new ValidateRecord();
						m.setAnnotationClass(Email.class);
						m.setMessage(f.getAnnotation(Email.class).message());
						m.setField(f.getName());
						s.add(m);
					}
				}
				if (f.isAnnotationPresent(TelPhone.class)) {
					Object o = getValueFromMethodName(f.getName(), t);
					if(o==null) {
						continue;
					}
					String telphone = o.toString();
					if(!telphone.matches(f.getAnnotation(TelPhone.class).reg())) {
						ValidateRecord m = new ValidateRecord();
						m.setAnnotationClass(TelPhone.class);
						m.setMessage(f.getAnnotation(TelPhone.class).message());
						m.setField(f.getName());
						s.add(m);
					}
				}
				if (f.isAnnotationPresent(Size.class)) {
					Object o = getValueFromMethodName(f.getName(), t);
					if(o==null) {
						continue;
					}
					String str = o.toString();
					Size an = f.getAnnotation(Size.class);
					if(an.Max()>0) {
						if(str.toString().length()>an.Max()) {
							ValidateRecord m = new ValidateRecord();
							m.setAnnotationClass(Size.class);
							m.setMessage(f.getAnnotation(Size.class).message());
							m.setField(f.getName());
							s.add(m);
						}
					}
					if(an.Min()>-1) {
						if(str.toString().length()<an.Min()) {
							ValidateRecord m = new ValidateRecord();
							m.setAnnotationClass(Size.class);
							m.setMessage(f.getAnnotation(Size.class).message());
							m.setField(f.getName());
							s.add(m);
						}
					}
				}
			}
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		return s;
	}
	private Object getValueFromMethodName(String base,T t) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
		String method = "get"+base.substring(0,1).toUpperCase()+base.substring(1);
		Method m = t.getClass().getMethod(method);
		Object o = m.invoke(t);
		return o;
	}
}
